package com.laizt.client.openexe;

import com.laizt.client.util.ShareFileUtils;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OpenExeClient {

    private static final Logger logger = LoggerFactory.getLogger(OpenExeClient.class.getName());
    //private static String dir = "D:\\N9M-TestTool";

    public static void ExeMain(Map<String,Object> resultMap,Map<String,Object> map, String remoteIp){
        String dir = (String) map.get("dir");
        //  String url = "smb://Desktop-u2bsdvd/111/";
        // smb://userName:passWord@host/path/
        //
        //删除本地某个目录所有文件
        File file = new File(dir);//输入要删除文件目录的绝对路径
        deleteFile(file,resultMap,map);
        if(resultMap.get("code").equals("01"))return;
        resultMap.put("msg","");
        //版本一样直接打开
        if(resultMap.get("code").equals("04")){
            logger.info("open redirect");
            resultMap.put("code","00");
            //应用程序所在的路径
            String path = createBatPath(dir);
            logger.info("bat路径:"+path);
            //打开exe
            openExe(resultMap,path);
        }else{
            logger.info("down and open");
            resultMap.put("code","00");
            //重试次数
            int count=0;
            // 从共享目录拉取文件并运行
            ShareFileUtils.getSharedFileList(resultMap,map,remoteIp,count);
            if("01".equals(resultMap.get("code")))return;
            //应用程序所在的路径
            String path = createBatPath(dir);
            if("01".equals(resultMap.get("code")))return;
            logger.info("bat路径:"+path);
            //打开exe
            openExe(resultMap,path);
        }
    }

    /**
     * 创建bat文件
     * @return
     */
    public static String createBatPath(String dir){
        File filePath = new File(dir);
        // 一、检查放置文件的文件夹路径是否存在，不存在则创建
        if (!filePath.exists()) {
            filePath.mkdirs();// mkdirs创建多级目录
        }
        File checkFile = new File(filePath + "/n9m.bat");
        FileWriter writer = null;
        StringBuilder sb = new StringBuilder();
        try {
            // 二、检查目标文件是否存在，不存在则创建
            if (!checkFile.exists()) {
                checkFile.createNewFile();// 创建目标文件
            }
            // 三、向目标文件中写入内容
            writer = new FileWriter(checkFile, false);
            sb.append("start /d ");
            sb.append("\""+dir+"\"");
            sb.append(" cp3testprogram.exe");
            String str = sb.toString();
            logger.info("batPath:"+str);
            writer.append(str);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return filePath + "/n9m.bat";
    }

    /**
     * 打开本地exe程序
     * @param batPath
     */
    public static void openExe(Map<String,Object> resultMap,String batPath) {
        Runtime rn = Runtime.getRuntime();
        Process p = null;
        try {
            logger.info("===打开bat==="+batPath);
            p = rn.exec(batPath);
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code","01");
            resultMap.put("msg","打开测试软件exe程序异常!");
        }
    }

    /**
     * 删除文件
     * @param file
     * @param resultMap
     * @param map
     */
    public static void deleteFile(File file,Map<String,Object> resultMap,Map<String,Object> map){
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            file.mkdirs();
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        String msg  = "";
        if(files.length>0){
            checkVer(files,resultMap,map);
            if(resultMap.get("code").equals("04")||resultMap.get("code").equals("01"))return;
            //遍历该目录下的文件对象
            for (File f: files){
                //判断子目录是否存在子目录,如果是文件则删除
                if (f.isDirectory()){
                    deleteFile(f,resultMap,map);
                }else {
                    String name = f.getName();
                    if("D5_CONFIG.cnf".equals(name)){
                        logger.info("==不需要删除本地D5_CONFIG.cnf文件==");
                        continue;
                    }
                   /* if("configer.txt".equals(name)){
                        logger.info("==不需要删除本地configer.txt文件==");
                        continue;
                    }*/
                    try{
                        f.delete();
                    }catch(Exception e){
                        e.printStackTrace();
                        continue;
                    }
                }
            }
        }else{ //没有文件一定要去下载
            map.put("code","2");
        }
    }


    /**
     * 获取本地VER.txt内容
     * @param files
     */
    public static Map<String,Object> getLocalString(File[] files){
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("code","01");
        for (File f: files){
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
               continue;
            }else {
                String name = f.getName();
                logger.info("本地文件名字："+name);
                if("VER.txt".equals(name)){
                    InputStream in = null;
                    try{
                        byte[] b = new byte[100];
                        in = new FileInputStream(f);
                        in.read(b);
                        String result = new String(b,"utf-8");
                        logger.info("本地版本文件内容："+result);
                        resultMap.put("msg",result);
                        resultMap.put("code","02");
                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                   break;
                }
            }
        }
        return resultMap;
    }




    /**
     * 检测软件版本，是否和服务器一样
     * @param files
     * @return
     */
    public static void checkVer(File[] files,Map<String,Object> resultMap,Map<String,Object> map){
        getVersion(resultMap, map);
        if("01".equals(resultMap.get("code")))return;
        Map<String,Object>  result = getLocalString(files);
        //有文件存在
        if("02".equals(result.get("code"))){
            if(result.get("msg").equals(resultMap.get("msg"))){
                resultMap.put("code","04");//跳过
            }else{
                resultMap.put("code","03");
            }
        }else{
            //必须下载
            resultMap.put("code","03");
        }
    }


    public static void getVersion(Map<String,Object> resultMap,Map<String,Object> map) {
        SmbFile smbFile;
        String remoteUrl = (String) map.get("remoteUrl");
        try {
            // smb://userName:passWord@host/path/
            logger.info("====实际请求的共享url===="+remoteUrl);
            smbFile = new SmbFile(remoteUrl);
            if (!smbFile.exists()) {
                resultMap.put("code","01");
                resultMap.put("msg","共享目录【"+remoteUrl+"】不存在！");
                return;
            } else {
                SmbFile[] files = smbFile.listFiles();
                boolean  hasXml = false;
                boolean hasVersion = false;
                //下载文件
                for (SmbFile f : files) {
                    try {
                        if(f.isDirectory()){
                            //如果是目录按找目录下载
                            continue;
                        }else{
                            logger.info("=========="+f.getName());
                            if("VER.txt".equals(f.getName())){
                                hasVersion=true;
                                getVersionInfo(remoteUrl,resultMap);
                            }
                            if("cp3testprogram.exe".equals(f.getName())){
                                hasXml = true;
                            }
                        }
                    } catch (SmbException e) {
                        e.printStackTrace();
                    }
                }
                if(!hasXml){
                    resultMap.put("code","01");
                    resultMap.put("msg","共享目录中未下载到可用的测试软件！");
                    return;
                }
                if(!hasVersion){
                    resultMap.put("code","01");
                    resultMap.put("msg","未维护VER.txt版本文件");
                    return;
                }
            }
        } catch (Exception e) {
            resultMap.put("code","01");
            resultMap.put("msg","请求共享目录【"+remoteUrl+"】失败！");
        }
    }





    //获取verson文件内容
    public static void getVersionInfo(String remoteUrl,Map<String,Object> resultMap){
        InputStream in = null;
        try{
            SmbFile remoteFile = new SmbFile(remoteUrl + File.separator + "VER.txt");
            in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
            byte[] bytes= new byte[100];
            in.read(bytes);
            String result = new String(bytes,"utf-8");
            logger.info("共享服务器版本文件内容："+result);
            resultMap.put("msg",result);
            resultMap.put("code","02");
        }catch (Exception e){
            e.printStackTrace();
            resultMap.put("code","01");
            resultMap.put("msg","请求共享目录【"+remoteUrl+"】失败！");
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String removeSpecialChar(String str){
        String s = "";
        if(str != null){
            // 定义含特殊字符的正则表达式
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            s = m.replaceAll("");
        }
        return s;
    }

}
